﻿using System;
using FunctionalCLR.Core;
using FunctionalCLR.Shell;
using Zove.Runtime;

namespace Zove.Shell.Core {
    public class ZoveShellInterpreter : Interpreter {

        public ZoveShellInterpreter(IContext context)
            : base(context) {
        }

        public ZoveShellInterpreter()
            : base(new ZoveShellContext()) {
            ZoveDependencyManager.Instance.FunctionManager 
                = Context.GetFunctionManager();
        }

        protected override object ProcessInternal(string stmt) {
            if (string.IsNullOrEmpty(stmt.Trim())) {
                return string.Empty;
            }

            Lexer lexer = new Lexer(stmt);
            Token token = lexer.PeekToken(1);
            Token nt = lexer.PeekToken(2);

            if (token.TokenType == TokenType.Identifier
                && nt.TokenType == TokenType.Identifier) {
                token = lexer.NextToken();
                string type = token.Value;

                int count = 0;
                do {
                    token = lexer.NextToken();
                    if (token.TokenType == TokenType.Semicolon) {
                        break;
                    } else if (token.TokenType == TokenType.Identifier) {
                        // add new instances
                        if (Context.HasVariable(nt.Value)) {
                            return String.Format(
                                "Instance {0} was already created.", token.Value);
                        }

                        RuntimeModel rm
                            = ZoveDependencyManager.Instance.RuntimeModelLoader.LoadByClassName(type);
                        if (rm == null) {
                            DefaultDependencyManager.Instance.Logger.WriteLog(
                                "Model {0} cannot be loaded.", type);
                            continue;
                        }

                        Instance instance = new Instance(type);
                        instance.Name = nt.Value;
                        instance.Model = rm;

                        (Context as ZoveShellContext).AddInstance(
                            nt.Value, instance);
                        count++;
                    }
                }
                while (lexer.HasMoreTokens());

                string result = string.Format("{0} instance(s) were created.", count);

                return result;
            }

            return base.ProcessInternal(stmt);
        }
    }
}
